<?php

namespace App\Kuafu\Pay\Controller\Internal;

use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Pay\Enum\PayCodeEnum;
use App\Kuafu\Pay\Model\CheckFileModel;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Service\PayListsService;
use App\Kuafu\Pay\Service\PayService;
use App\Kuafu\Pay\Service\ShopPayService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class PayController extends BaseController
{
    public function demo()
    {
        return $this->success(['hello world~']);
    }

    /**
     * 直连app支付
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function directAppPay(Request $request)
    {
        $orderId     = $request->get('orderId');
        $subject     = $request->get('subject', '');
        $amount      = (int)$request->get('amount');
        $payChannel  = (int)$request->get('payChannel');
        $callbackUrl = (string)$request->get('callbackUrl', '');
        $shopId      = (int)$request->get('shopId');
        $sysType     = (int)$request->get('sysType');
        $bizId       = (string)$request->get('bizId');
        $expireTime  = (int)$request->get('expireTime', 0);
        $userId      = (int)$request->get('userId');

        $payeeConfigId = (int)$request->get('payeeConfigId', 0);// companyId

        if (!in_array($payChannel, [
            PayStreamModel::PAY_CHANNEL_ALI,
            PayStreamModel::PAY_CHANNEL_WX,
            PayStreamModel::PAY_CHANNEL_MYBANK_PAY,
            PayStreamModel::PAY_CHANNEL_MYBANK_CASHIER_PAY,
        ])) {
            return $this->fail(PayCodeEnum::ERR_APP_PAY_CHANNEL);
        }

        if (!in_array($sysType, array_keys(PayStreamModel::SYS_TYPE_TEXT))) {
            return $this->fail(PayCodeEnum::ERR_APP_PAY_SYS_TYPE);
        }

        return $this->success(PayService::sAppPay($shopId, $subject, $amount, $orderId, $payChannel, 0, $sysType,
            $callbackUrl, $bizId, $expireTime, $userId, $payeeConfigId));
    }

    /**
     * 关闭支付单
     * @param Request $request
     * @return
     */
    public function closePay(Request $request)
    {
        $orderId = (string)$request->post('orderId', '');
        $shopId  = (int)$request->post('shopId');
        $sysType = (int)$request->get('sysType');

        $this->validate($request, [
            'orderId' => 'required',
            'shopId'  => 'required|integer',
            'sysType' => 'required|integer',
        ]);

        return $this->success(PayService::sClosePay($orderId, $shopId, $sysType));
    }

    /**
     * 退款
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function directAppRefund(Request $request)
    {
        $shopId      = (int)$request->get('shopId');
        $orderId     = (string)$request->get('orderId');
        $amount      = (int)$request->get('amount');
        $callbackUrl = (string)$request->get('callbackUrl', '');
        $subject     = (string)$request->get('subject', '');
        $payNo       = (string)$request->get('payNo', '');

        return $this->success(PayService::sRefund($shopId, $orderId, $amount, $callbackUrl, $payNo, $subject));
    }

    /**
     * 新增富友支付配置
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Kuafu\Shop\Exceptions\ShopException
     */
    public function addFyConfig(Request $request)
    {
        $shopId      = (int)$request->get('shopId');
        $mchId       = trim((string)$request->get('mchId'));
        $mchKey      = trim((string)$request->get('mchKey'));
        $orderPrefix = trim((string)$request->get('orderPrefix'));

        $id = ShopPayService::addFyConfig($shopId,  $mchId,  $mchKey,  $orderPrefix);

        return $this->success(['id' => $id]);
    }

    /**
     * 新增网商分账配置
     * @param Request $request
     */
    public function addMyBankShareConfig(Request $request)
    {
        $shopId = $request->post('shopId');
        $config = $request->post('config');

        $this->validate($request, [
            'shopId'                      => 'required|integer|min:1',
            'config'                      => 'required|array',
            'config.rule'                 => 'required|array',
            'config.rule.*.startPrice'    => 'required|integer:min:0',
            'config.rule.*.endEqPrice'    => 'required|integer:min:0',
            'config.rule.*.type'          => 'required|string',
            'config.rule.*.percent'       => 'required|numeric',
            'config.isStop'               => 'required|boolean',
            'config.isPause'              => 'required|boolean',
            'config.pauseRule'            => 'array',
            'config.stopRule'             => 'array',
            'config.stopRule.totalAmount' => 'integer|min:0',
        ]);

        $id = ShopPayService::addMyBankShareConfig($shopId, $config);

        return $this->success(['id' => $id]);
    }

    public function delFyConfig(Request $request)
    {
        $shopId = (int)$request->get('shopId');

        ShopPayService::sDel($shopId);

        return $this->success();
    }

    /**
     * H5支付
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function wapPay(Request $request)
    {
        $orderId     = $request->get('orderId');
        $subject     = $request->get('subject', '');
        $amount      = (int)$request->get('amount');
        $payChannel  = (int)$request->get('payChannel');
        $callbackUrl = (string)$request->get('callbackUrl', '');
        $h5BackUrl   = (string)$request->get('h5BackUrl', '');
        $shopId      = (int)$request->get('shopId');
        $sysType     = (int)$request->get('sysType');
        $bizId       = (string)$request->get('bizId');

        if (!in_array($payChannel, [PayStreamModel::PAY_CHANNEL_ALI, PayStreamModel::PAY_CHANNEL_WX])) {
            return $this->fail(PayCodeEnum::ERR_APP_PAY_CHANNEL);
        }

        if (!in_array($sysType, array_keys(PayStreamModel::SYS_TYPE_TEXT))) {
            return $this->fail(PayCodeEnum::ERR_APP_PAY_SYS_TYPE);
        }

        return $this->success(PayService::sWapPay($shopId, $subject, $amount, $orderId, $payChannel, 0, $sysType,
            $callbackUrl, $h5BackUrl, $bizId));
    }

    /**
     * native支付
     * @param Request $request
     * @return JsonResponse
     */
    public function nativePay(Request $request)
    {
        $orderId     = $request->get('orderId');
        $subject     = $request->get('subject', '');
        $amount      = (int)$request->get('amount');
        $payChannel  = (int)$request->get('payChannel');
        $shopId      = (int)$request->get('shopId');
        $sysType     = (int)$request->get('sysType');
        $bizId       = (string)$request->get('bizId');
        $expireTime  = (int)$request->get('expireTime');
        $extra       = (array)$request->get('extra');

        if (!in_array($payChannel, [PayStreamModel::PAY_CHANNEL_WX])) {
            return $this->fail(PayCodeEnum::ERR_NATIVE_PAY_CHANNEL);
        }

        if (!in_array($sysType, array_keys(PayStreamModel::SYS_TYPE_TEXT))) {
            return $this->fail(PayCodeEnum::ERR_APP_PAY_SYS_TYPE);
        }

        return $this->success(PayService::sNativePay($shopId, $subject, $amount, $orderId, $payChannel, 0, $sysType, $bizId, $expireTime, $extra));
    }

    /**
     * 批量支付详情
     * @param Request $request
     * @return JsonResponse
     */
    public function payDetails(Request $request): JsonResponse
    {
        $payNos    = (array)$request->get('payNos');
        $orderIds  = (array)$request->get('orderIds');
        $sysTypes  = (array)$request->get('sysTypes');
        $pageSize  = (int)$request->get('pageSize');
        $pageNum   = (int)$request->get('pageNum');
        $startTime = (int)$request->get('startTime');
        $endTime   = (int)$request->get('endTime');
        $field     = (array)$request->get('field', ['*']);

        $data = (new PayListsService())
            ->setOrderIds($orderIds)
            ->setStartTime($startTime)
            ->setEndTime($endTime)
            ->setPageNum($pageNum)
            ->setPageSize($pageSize)
            ->setSysTypes($sysTypes)
            ->setPayNos($payNos)
            ->setField($field)
            ->payStreamLists();

        return $this->success($data);
    }

    /**
     * 支付结果查询
     * @param Request $request
     * @return JsonResponse
     */
    public function payResult(Request $request): JsonResponse
    {
        $payNo = $request->get('payNo');

        $data = PayStreamModel::suffix(null)
                              ->when(is_string($payNo), function ($query) use ($payNo) {
                                  $query->where('payNo', $payNo);
                              })
                              ->when(is_array($payNo), function ($query) use ($payNo) {
                                  $query->whereIn('payNo', $payNo);
                              })
                              ->get()
                              ->toArray();

        return $this->success($data);
    }

    /**
     * 获取对账文件地址
     * @param Request $request
     * @return JsonResponse
     */
    public function getCheckFileUrl(Request $request): JsonResponse
    {
        if (!$request->get('date')) {
            return $this->fail(PayCodeEnum::ERR_REQUEST_PARAM, '参数错误');
        }

        $date = (int)date('Ymd', strtotime($request->get('date')));

        $lists = CheckFileModel::query()
                               ->where('date', $date)
                               ->get()
                               ->map(function ($item) {
                                   return [
                                       'payChannel' => $item->payChannel,
                                       'date'       => $item->date,
                                       'url'        => $item->url,
                                       'company'    => $item->company,
                                   ];
                               });

        return $this->success(['lists' => $lists]);
    }
}
